#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int T,n,m,L,V,p[N],b[35];
bool flag[N];
struct node
{
	int start,end;
}car[N];
int nn(double oo)
{
	if(oo==int(oo)) return oo+1;
	else return int(oo+1);
}
int cal(int d1,int v1,int a1)
{
	if(a1==0)
	{
		if(v1>V) return L;
		else return -1;
	}
	if(a1>0)
	{
		if(v1>V) return d1;
		else return nn(d1+double(V*V-v1*v1)/(2*a1));
	}
	if(a1<0)
	{
		if(v1<=V) return -1;
		else return nn(d1+double(V*V-v1*v1)/(2*a1));
	}
	return -2;
}
void firstset()
{
	for(int z=1;z<=N;z++) flag[z]=0;
	for(int z=1;z<=N;z++) car[z].start=-1;
	for(int z=1;z<=N;z++) car[z].end=-1;
	for(int z=1;z<=N;z++) p[z]=-1;
	return;
}
int main()
{
	freopen("detect.in","r",stdin);
	freopen("detect.out","w",stdout);
	scanf("%d",&T);
	while(T!=0)
	{
		T--;
		scanf("%d%d%d%d",&n,&m,&L,&V);
		firstset();
		for(int i=1;i<=n;i++)
		{
			int d,v,a;
			scanf("%d%d%d",&d,&v,&a);
			if(a==0)
			{
				car[i].start=d;
				car[i].end=cal(d,v,a);
			}
			if(a>0)
			{
				car[i].start=cal(d,v,a);
				car[i].end=L;
			}
		}
		for(int i=1;i<=m;i++) scanf("%d",&p[i]);
		sort(p,p+m);
		int k=p[m],cnt=0;
		for(int i=1;i<=n;i++)
		{
			if(car[i].end!=-1&&car[i].start<=k&&k<=car[i].end) cnt++;
		}
		if(cnt==0) printf("%d %d\n",cnt,m);
		else printf("%d %d\n",cnt,m-1);
	}
	return 0;
}
